package com.cxlin.base.ext

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

/**
 *
 * @Author: chenxunlin
 * @Date: 2024/4/25 10:29
 */

fun Context.toast(content:String,duration:Int = Toast.LENGTH_SHORT){
    Toast.makeText(this, content, duration).apply {
        show()
    }
}


inline fun <reified VB : ViewDataBinding> AppCompatActivity.binding(layoutId: Int): Lazy<VB> {

    return lazy {
        DataBindingUtil.setContentView<VB>(this@binding, layoutId).apply {
            lifecycleOwner = this@binding
        }
    }

}

inline fun <reified T: AppCompatActivity> Context.startActivity(data: Bundle? = null){
    val intent = Intent(this,T::class.java).apply {
        if(data!=null){
            putExtras(data)
        }
    }
    startActivity(intent)
}

inline fun <reified T:Fragment> Context.newInstanceFragment(data: Bundle? = null):T{
    val fragment = T::class.constructors.first().call()
    data?.run {
        fragment.arguments = data
    }
    return fragment
}


fun <T> extraActivity(name: String): ActivityExtras<T?> = ActivityExtras(name, null)

fun <T> extraActivity(name: String, defaultValue: T) = ActivityExtras(name, defaultValue)

fun <T> extraFragment(name: String): FragmentExtras<T?> = FragmentExtras(name, null)

fun <T> extraFragment(name: String, defaultValue: T) = FragmentExtras(name, defaultValue)


class ActivityExtras<T>(private val name: String, private val defaultValue: T) :
    ReadOnlyProperty<Activity, T> {

    private var extra: T? = null

    override fun getValue(thisRef: Activity, property: KProperty<*>): T {
        return extra
            ?: thisRef.intent?.extras?.take<T>(name)?.also { extra = it }
            ?: defaultValue.also { extra = it }
    }
}


class FragmentExtras<T>(private val name: String, private val defaultValue: T) :
    ReadOnlyProperty<Fragment, T> {

    private var extra: T? = null

    override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
        return extra
            ?: thisRef.arguments?.take<T>(name)?.also { extra = it }
            ?: defaultValue.also { extra = it }
    }
}

@Suppress("UNCHECKED_CAST")
fun <T> Bundle.take(key: String): T? {
    try {
        return get(key) as? T?
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return null
}

